#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "HttpDefine.h"
#include "Engine.h"
#include "HttpProtocolParse.h"


using namespace std;
using namespace HttpFrame::Loger;

namespace HttpFrame
{


std::string HandlerKey::Key(int nCmdType)
{
    char szBuf[50]={0};
    memset(szBuf,0,sizeof(szBuf));
    snprintf(szBuf,sizeof(szBuf)-1,"%d",nCmdType);
    return szBuf;
}

std::string HandlerKey::Key(const char *pszCmdType)
{
    return pszCmdType;
}

std::string HandlerKey::Key(const std::string &strCmdType)
{
    return strCmdType;
}

COperationEngine::COperationEngine()
{
         log_=NULL;
         m_pReqBuffer=NULL;
         m_nReqBufferSize=0;
         m_pRspBuffer=NULL;
         m_nRspBufferSize=0;
         m_nIsLongConn=1;
}

COperationEngine::~COperationEngine()
{
}

int COperationEngine::Init(CIniFile &ini)
    	//,spp::comm::CServerBase *server)
{  
    //Server(server);
    
    m_strCmdName=ini.GetString("httpframe","cmd_name","X_CMD");
    m_strVersionName=ini.GetString("httpframe","version_name","X_VERSION");
    m_strClientName=ini.GetString("httpframe","client_name","HttpFrameClient");
    m_strServerName=ini.GetString("httpframe","server_name","HttpFrameServer");
    std::string strLogPath=ini.GetString("httpframe","log_path","../log");
    std::string strLogPrefix=ini.GetString("httpframe","log_prefix","httpframe");

    m_nIsLongConn = ini.GetInt("httpframe","is_long_conn",1);
    m_nIsAsynMode = ini.GetInt("httpframe","is_Asyn_mode",0);

    m_nReqBufferSize=ini.GetInt("httpframe","req_buffer_size",HF_MAX_PACK_LEN);
    m_nRspBufferSize=ini.GetInt("httpframe","rsp_buffer_size",HF_MAX_PACK_LEN);

    m_pReqBuffer=new char[m_nReqBufferSize];
    if(m_pReqBuffer==NULL)
    {
        COperationEngine::Finit();
        return -1;
    }
    
    m_pRspBuffer=new char[m_nRspBufferSize];

    if(m_pRspBuffer==NULL)
    {
        COperationEngine::Finit();
        return -1;
    }

    int nLogLevel =ini.GetInt("httpframe","log_level",HttpFrame::Loger::LOG_DEBUG);

    log_=new CLog();

    if(log_==NULL)
    {
        COperationEngine::Finit();
        return -1;
    }
    if(log_->log_open(nLogLevel,HttpFrame::Loger::LOG_TYPE_CYCLE,strLogPath.c_str(),strLogPrefix.c_str(),1024*1024*10,10))
    {
        COperationEngine::Finit();
        return -1;
    }
    
    if(Register(ini))
    {
        COperationEngine::Finit();
        return -1;
    }
    
    return 0;
    
}

int COperationEngine::Finit()
{
    if(m_pReqBuffer!=NULL)
    {
        delete[] m_pReqBuffer;
        m_pReqBuffer=NULL;
    }
    if(m_pRspBuffer!=NULL)
    {
        delete[] m_pRspBuffer;
        m_pRspBuffer=NULL;
    }
    if(log_!=NULL)
    {
        delete log_;
        log_=NULL;
    }
    return 0;
}

void COperationEngine::SetHandlerParam(void *pParam)
{
    handler_pool_t::iterator itr =handler_pool_.begin();

    for(;itr!=handler_pool_.end();itr++)
    {
        itr->second->SetAsynParam(pParam);
    }
}

int COperationEngine::RegisterHandler(const std::string &strKey,COperatinHandler *pHandler)
{
    if(handler_pool_.insert(std::make_pair(strKey,pHandler)).second==false)
    {
        return -1;
    }
    return 0;
}

int  COperationEngine::GetCmd(CHttpProtocolParse& reqParase,char *szCmd,int nCmdSize)
{
    return reqParase.GetPara(m_strCmdName.c_str(),szCmd,nCmdSize);
}
/*
int COperationEngine::ProcessPack(void *pConn,
	                                    const char *pszReqPack,
     	                                    int      iReqPackLen,
     	                                    char *pszRspPack,
     	                                    int       iRspPackBufLen,
     	                                    int       &iRspPackLen)
     	                                    */
int COperationEngine::ProcessPack(void *pConn,CHttpProtocolParse &reqParase,CHttpProtocolParse &rspParase)
{

     //Server()->log_.LOG_P(LOG_DEBUG, "COperationEngine::ProcessPack, ProcessPack:%s \n", pszReqPack);
 
     int  nRet = 0;
     char achValue[HF_HTTP_PARA_VALUE_LEN_LIMIT]={0};
     memset(achValue,0,sizeof(achValue));
 /*
     CHttpProtocolParse reqParase((char*)pszReqPack,iReqPackLen
 		,m_strCmdName.c_str()
 		,m_strVersionName.c_str()
 		,m_strClientName.c_str()
 		,m_strServerName.c_str());
 
     reqParase.ConnInfo(pConn);
    
     CHttpProtocolParse rspParase(pszRspPack,iRspPackBufLen
 		,m_strCmdName.c_str()
 		,m_strVersionName.c_str()
 		,m_strClientName.c_str()
 		,m_strServerName.c_str());
     */

// Logger()->LOG_P(LOG_ERROR, "COperationEngine::ProcessPack, can't find cmd:%s's handler,handler_pool_.size=%d,char=%c,%d\n", achValue,handler_pool_.size(),achValue[strlen(achValue)-1],int(achValue[strlen(achValue)-1]));

     if(GetCmd(reqParase,achValue,sizeof(achValue))!=0)
     {
         rspParase.MakeRespone(400, "Bad Request ", 0, 0,NULL, 0);
         return -1;
     }
     //std::string strKey = achValue;
     
     handler_pool_t::iterator itr =handler_pool_.find(achValue);
 
     if(itr==handler_pool_.end())
     {
         rspParase.MakeRespone(400, "Bad Request ", 0, 0, NULL, 0);
         Logger()->LOG_P(HttpFrame::Loger::LOG_ERROR, "COperationEngine::ProcessPack, can't find cmd:%s's handler,handler_pool_.size=%d,char=%c,%d\n", achValue,handler_pool_.size(),achValue[strlen(achValue)-1],int(achValue[strlen(achValue)-1]));
         return -2;
     }
 
     if(CommProcess(pConn,reqParase,rspParase))
     {
         return -3;
     }
 
     nRet = itr->second->ProcessPack(this
     	                                                      ,reqParase
     	                                                      ,rspParase);
 
     //iRspPackLen = rspParase.GetPackLen();

     //if(iRspPackLen==0)
     //{
     //    return -1;
     //}

     return 0;
     
}

int COperationEngine::CommProcess(void *pConn,CHttpProtocolParse &reqParase,CHttpProtocolParse &rspParase)
{
    char szExchange[125]={0};
    memset(szExchange,0,sizeof(szExchange));
    if(reqParase.GetPara("X_EXCHANGE", szExchange,sizeof(szExchange))==0)
    {
        rspParase.AddExtPara("X_EXCHANGE", szExchange);
    }
    return 0;
}

void COperationEngine::ResetBuffer()
{
    //memset(m_pReqBuffer,0,m_nReqBufferSize);
    //memset(m_pRspBuffer,0,m_nRspBufferSize);
    m_pReqBuffer[m_nReqBufferSize]=m_pReqBuffer[0]=0;
    m_pRspBuffer[m_nRspBufferSize]=m_pRspBuffer[0]=0;
}

}

